package com.yuandian.management.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yuandian.api.business_monitor.feign.RemoteBaseAlarmService;
import com.yuandian.api.business_monitor.vo.AlarmIndicatorsVo;
import com.yuandian.api.management.annotation.UpdateConfig;
import com.yuandian.api.management.entity.*;
import com.yuandian.bpm.admin.api.entity.SysDictItem;
import com.yuandian.bpm.admin.api.feign.RemoteDictService;
import com.yuandian.bpm.common.core.util.R;
import com.yuandian.bpm.common.security.util.SecurityUtils;
import com.yuandian.constant.DictType;
import com.yuandian.management.mapper.ConfAlarmIndicatorsMapper;
import com.yuandian.management.service.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 指标信息-Service实现
 * @author zfsn
 * @date 2023-4-4
 */
@Service
public class ConfAlarmIndicatorsServiceImpl extends ServiceImpl<ConfAlarmIndicatorsMapper, ConfAlarmIndicators>
		implements ConfAlarmIndicatorsService {


	@Autowired
	RemoteBaseAlarmService remoteBaseAlarmService;
	@Autowired
	ConfAlarmIndicatorsMapper confAlarmIndicatorsMapper;

	@Autowired
	ConfAlarmIndicatorsHisService confAlarmIndicatorsHisService;

	@Autowired
	ConfAlarmService confAlarmService;

	@Autowired
	ConfAlarmThresholdService confAlarmThresholdService;

	@Autowired
	RemoteDictService remoteDictService;

	@Autowired
	ConfAlarmIndicatorUnitService confAlarmIndicatorUnitService;

	/**
	 * 通过主键查询数据
	 *
	 * @param id 主键集合
	 * @return 通用返回对象
	 */
	@Override
	public ConfAlarmIndicators getById(Integer id) {
		ConfAlarmIndicators confAlarmIndicators = super.getById(id);
		Map<String, String> alarmIndicatorType = remoteDictService.getDictByType(DictType.CONF_ALARM_INDICATOR_OBJ_TYPE).getData().stream().collect(Collectors.toMap(SysDictItem::getItemValue, SysDictItem::getLabel));
		Map<String, String> alarmParticleType = remoteDictService.getDictByType(DictType.CONF_ALARM_PARTICLE_TYPE).getData().stream().collect(Collectors.toMap(SysDictItem::getItemValue, SysDictItem::getLabel));
		confAlarmIndicators.setIndicatorsObject(alarmIndicatorType.get(String.valueOf(confAlarmIndicators.getObjId())));
		confAlarmIndicators.setParticleName(alarmParticleType.get(String.valueOf(confAlarmIndicators.getParticleId())));
		ConfAlarmIndicatorUnit unitServiceById = confAlarmIndicatorUnitService.getById(confAlarmIndicators.getUnit());
		if (unitServiceById != null){
			confAlarmIndicators.setUnitName(unitServiceById.getName());
		}
		return confAlarmIndicators;
	}

	/**
	 * 分页查询
	 *
	 * @param confAlarmIndicators 筛选条件
	 * @return 通用返回对象
	 */
	@Override
	public Page<ConfAlarmIndicators> listPage(ConfAlarmIndicators confAlarmIndicators) {
		Page<ConfAlarmIndicators> confAlarmIndicatorsPage = confAlarmIndicatorsMapper.listPage(new Page<>(confAlarmIndicators.getPageNum(), confAlarmIndicators.getPageSize()), confAlarmIndicators);
		Map<String, String> alarmIndicatorType = remoteDictService.getDictByType(DictType.CONF_ALARM_INDICATOR_OBJ_TYPE).getData().stream().collect(Collectors.toMap(SysDictItem::getItemValue, SysDictItem::getLabel));
		Map<String, String> alarmParticleType = remoteDictService.getDictByType(DictType.CONF_ALARM_PARTICLE_TYPE).getData().stream().collect(Collectors.toMap(SysDictItem::getItemValue, SysDictItem::getLabel));
		Map<String, String> indicatorObject = remoteDictService.getDictByType(DictType.SYS_INDICATORS_OBJECT).getData().stream().collect(Collectors.toMap(SysDictItem::getItemValue, SysDictItem::getLabel));
		Map<Integer, String> stringMap = confAlarmIndicatorUnitService.list().stream().collect(Collectors.toMap(ConfAlarmIndicatorUnit::getId, ConfAlarmIndicatorUnit::getName));
		for (ConfAlarmIndicators indicatorsPageRecord : confAlarmIndicatorsPage.getRecords()) {
			indicatorsPageRecord.setIndicatorsObject(alarmIndicatorType.get(String.valueOf(indicatorsPageRecord.getObjId())));
			indicatorsPageRecord.setParticleName(alarmParticleType.get(String.valueOf(indicatorsPageRecord.getParticleId())));
			indicatorsPageRecord.setObjName(indicatorObject.get(String.valueOf(indicatorsPageRecord.getObjId())));
			indicatorsPageRecord.setUnitName(stringMap.get(indicatorsPageRecord.getUnit()));
		}
		return confAlarmIndicatorsPage;
	}

	/**
	 * 新增数据
	 *
	 * @param confAlarmIndicators 实例对象
	 * @return 通用返回对象
	 */
	@Override
	public R<String> saveConfig(ConfAlarmIndicators confAlarmIndicators) {
		if (Objects.equals(confAlarmIndicators.getType(), 2) && !checkExpression(confAlarmIndicators)){
			return R.failed("表达式校验不通过");
		}
		if (duplicateIndicatorName(confAlarmIndicators)){
			return R.failed("指标名称存在重复");
		}
		confAlarmIndicators.setCreateBy(SecurityUtils.getUser().getName());
		super.save(confAlarmIndicators);
		return R.ok();
	}

	/**
	 * 通过主键更新数据
	 *
	 * @param confAlarmIndicators 实例对象
	 * @return 通用返回对象
	 */
	@Override
	@UpdateConfig
	public R<String> updateConfigById(ConfAlarmIndicators confAlarmIndicators) {
		if (Objects.equals(confAlarmIndicators.getType(), 2) &&!checkExpression(confAlarmIndicators)){
			return R.failed("表达式校验不通过");
		}
		if (duplicateIndicatorName(confAlarmIndicators)){
			return R.failed("指标名称存在重复");
		}
		ConfAlarmIndicatorsHis confAlarmIndicatorsHis = new ConfAlarmIndicatorsHis();
		confAlarmIndicatorsHis.setCode( confAlarmIndicators.getId());
		confAlarmIndicatorsHis.setType(confAlarmIndicators.getType());
		confAlarmIndicatorsHis.setName(confAlarmIndicators.getName());
		confAlarmIndicatorsHis.setUnit(confAlarmIndicators.getUnit());
		confAlarmIndicatorsHis.setDescription(confAlarmIndicators.getDescription());
		confAlarmIndicatorsHis.setExpression(confAlarmIndicators.getExpression());
		confAlarmIndicatorsHisService.save(confAlarmIndicatorsHis);
		super.updateById(confAlarmIndicators);
		return R.ok();
	}

	/**
	 * 通过主键删除数据
	 * @param ids 主键
	 * @return 通用返回对象
	 */
	@Override
	@UpdateConfig
	public R<String> removeConfigByIds(List<Integer> ids) {
		QueryWrapper<ConfAlarm> alarmQueryWrapper = new QueryWrapper<>();
		alarmQueryWrapper.in("alarm_indicator_id", ids);
		List<Integer> alarmIds = confAlarmService.list(alarmQueryWrapper).stream().map(ConfAlarm::getId).collect(Collectors.toList());
		if (!alarmIds.isEmpty()) {
			//删除告警阈值信息
			UpdateWrapper<ConfAlarmThreshold> thresholdUpdateWrapper = new UpdateWrapper<>();
			thresholdUpdateWrapper.in("alarm_id", alarmIds);
			confAlarmThresholdService.remove(thresholdUpdateWrapper);
			confAlarmService.removeByIds(alarmIds);
		}
		super.removeBatchByIds(ids);
		return R.ok();
	}

	/**
	 * 是否禁用指标
	 *
	 * @param confAlarmIndicators
	 * @return 结果
	 */
	@Override
	@UpdateConfig
	@Transactional(rollbackFor = Exception.class)
	public R<String> updateIndicatorsEnable(ConfAlarmIndicators confAlarmIndicators) {
		ConfAlarmIndicators alarmIndicators = super.getById(confAlarmIndicators.getId());
		if (alarmIndicators != null) {

			//修改数据之前，将旧数据记录历史表中
			ConfAlarmIndicatorsHis confAlarmIndicatorsHis = new ConfAlarmIndicatorsHis();
			BeanUtils.copyProperties(alarmIndicators, confAlarmIndicatorsHis);
			// 避免出现主键冲突异常
			confAlarmIndicatorsHis.setId(null);
			confAlarmIndicatorsHisService.save(confAlarmIndicatorsHis);
			UpdateWrapper<ConfAlarmIndicators> indicatorsUpdateWrapper = new UpdateWrapper<>();
			indicatorsUpdateWrapper.eq("id", confAlarmIndicators.getId());
			indicatorsUpdateWrapper.set("is_enable", confAlarmIndicators.getIsEnable());
			super.update(indicatorsUpdateWrapper);
			return R.ok("修改告警状态成功");
		}
		return R.failed();
	}

	/**
	 * 通过主键更新自定义告警指标数据
	 *
	 * @param confAlarmIndicators
	 * @return 通用返回对象
	 * @Description type = 1, 告警类型为基础告警
	 */
	@Override
	public List<Map<Integer, Integer>> getBaseAlarmIndicatorsAndCode(ConfAlarmIndicators confAlarmIndicators) {
		return confAlarmIndicatorsMapper.getBaseAlarmIndicatorsAndCode(confAlarmIndicators);
	}

	/**
	 * 根据指标对象值查询指标编码
	 *
	 * @param objValue
	 * @return 通用返回对象
	 */
	@Override
	public R queryCodeList(Integer objValue) {
		return R.ok(confAlarmIndicatorsMapper.queryCodeList(objValue));
	}

	/**
	 * 校验表达式
	 * @param confAlarmIndicators
	 * @return
	 */
	private boolean checkExpression(ConfAlarmIndicators confAlarmIndicators){
		AlarmIndicatorsVo alarmIndicatorsVo = new AlarmIndicatorsVo();
		alarmIndicatorsVo.setObjId(confAlarmIndicators.getObjId());
		alarmIndicatorsVo.setExpression(confAlarmIndicators.getExpression());
		return remoteBaseAlarmService.checkExpression(alarmIndicatorsVo).getCode() == 0;
	}

	/**
	 * 判断指标名称是否重复
	 * @param confAlarmIndicators
	 * @return
	 */
	private boolean duplicateIndicatorName(ConfAlarmIndicators confAlarmIndicators){
		QueryWrapper<ConfAlarmIndicators> confAlarmIndicatorsQueryWrapper = new QueryWrapper<>();
		confAlarmIndicatorsQueryWrapper.eq("name", confAlarmIndicators.getName());
		if (confAlarmIndicators.getId() != null) {
			confAlarmIndicatorsQueryWrapper.ne("id", confAlarmIndicators.getId());
		}
		return !super.list(confAlarmIndicatorsQueryWrapper).isEmpty();
	}
}
